How To Build GCC/G++ 4.3.3 AVR 32-bit Cross-Compiler


Intro


In this How To we are going to build an ARM cross-compiler based upon GCC/G++ 4.3.3. Before you begin you might want to take a look at my build machine specs to get an idea of what I'm running on compared to your machine. In the least please make sure you have enough memory. Do not expect a flawless build, especially if you are only running with 1 to 2 GB of memory 8P If you run into issues try to figure them out.

Why would I want to do this you ask? Especially when there are numerous tools/scripts out there that do it for you!? First of all, I can use this to play on the newest Arduino SBC - Arduino Zero! Second, there are too many tools/scripts out there that do this for you. I want to learn how to do this myself, so I'm not "vendor locked" to one of these tools ;-P

Tar Balls


Here is a list of source packages that we'll need for the build. You can either download them now or wait 'til later in the How To.
  • binutils-2.20.1.tar.bz2
  • glibc-2.9.tar.gz
  • glibc-ports-2.9.tar.bz2
  • gcc-4.3.3.tar.gz
  • gmp-4.3.1.tar.bz2
  • mpfr-2.4.1.tar.bz2
  • linux-2.6.38.tar.bz2
  • atmel patches for binutils-2.20.1
  • atmel patches for gcc-4.3.3

Create a Workspace


I recommend creating a workspace under your /home/<your user>/ directory that is dedicated to this build. So let's fire up your terminal and run the following:
$ export SRCDIR=~/workbench/AVR/AVR32/gcc-g++-4.3.3/xtools/src
$ mkdir -pv ~/workbench/AVR/AVR32/gcc-g++-4.3.3/xtools
$ mkdir $SRCDIR
$ cd $SRCDIR

Gather the Sources


Now that we have a workspace created and we are currently in the src directory we can begin bringing down the sources and extracting them.

binutils

$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.bz2
$ tar -pxjf binutils-2.20.1.tar.bz2

glibc

$ tar -pxzf glibc-2.9.tar.gz
$ cd glibc-2.9/
$ tar -pxjf ../glibc-ports-2.9.tar.bz2
$ cd $SRCDIR

gcc

$ tar -pxzf gcc-4.3.3.tar.gz
$ cd gcc-4.3.3/
$ tar -pxjf ../gmp-4.3.1.tar.bz2
$ tar -pxjf ../mpfr-2.4.1.tar.bz2
$ mv gmp-4.3.1/ gmp
$ mv mpfr-2.4.1/ mpfr
$ cd $SRCDIR

kernel

$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.38.tar.bz2
$ tar -pxjf linux-2.6.38.tar.bz2

binutils - atmel patch

$ cd ../
$ mkdir -pv atmel-patches
$ cd atmel-patches/
$ mkdir -pv binutils-2.20.1
$ cd binutils-2.20.1/
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/20-binutils.2.20.1-avr32-autoconf.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/30-binutils-2.20.1-avr32-bfd.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/31-binutils-2.20.1-avr32-binutils.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/32-binutils-2.20.1-avr32-gas.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/33-binutils-2.20.1-avr32-include.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/34-binutils-2.20.1-avr32-ld.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/35-binutils-2.20.1-avr32-opcodes.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/40-binutils-2.20.1-avr32-fixes.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/41-binutils-2.20.1-avr32-fpu.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/42-binutils-2.20.1-avr32-bug-7435.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/50-binutils-2.20.1-avr32-mxt768e.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/51-binutils-2.20.1-avr32-uc3c.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/52-binutils-2.20.1-avr32-uc3l0128.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/53-binutils-2.20.1-avr32-uc3a4.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/54-binutils-2.20.1-avr32-uc3d.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/binutils-2.20.1/55-binutils-2.20.1-avr32-uc3l3l4.patch
I recommend making a patchset for the above patches before continuing. Now apply the patches:
$ cd $SRCDIR/binutils-2.20.1/
$ for patch in `cat ../../atmel-patches/binutils-2.20.1/patchset`; do patch -Np0 -i ../../atmel-patches/binutils-2.20.1/$patch; done
Check the output from the above command to make sure there was no error. If you get an error make sure you are in the correct directory when running patch.

Now that we modified some of the source files in binutils-2.20.1 we need to re-generate some configure scripts. We do this by running automake and autoreconf. But before that we need to make a change to override.m4 in $SRCDIR/binutils-2.20.1/config. Open this file in your favorite text editor and look for the following line:
...
...
dnl Ensure exactly this Autoconf version is used
m4_ifndef([_GCC_AUTOCONF_VERSION],
  [m4_define([_GCC_AUTOCONF_VERSION], [2.64])])
...
...
Change 2.64 to your autoconf version. For me, it is 2.69:
$ autoconf -V
autoconf (GNU Autoconf) 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+/Autoconf: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>, <http://gnu.org/licenses/exceptions.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
Written by David J. MacKenzie and Akim Demaille.
Now we can run automake and autoreconf in binutils-2.20.1 source directory and *all* of its subdirectories. Some of the subdirectories do not need them, but I'll let you experience that for yourself ;P You'll get some output from the automake and autoreconf about the command failing, configure.in should be called configure.ac and the like. You can safely ignore all of this. This most important part is that you run both commands in binutils-2.20.1 source directory and *all* of its subdirectories.

gcc-4.3.3 - atmel patch

$ cd $SRCDIR/ && cd ../atmel-patches/
$ mkdir -pv gcc-4.3.3 && cd gcc-4.3.3/
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/30-gcc-4.3.3-avr32.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/31-gcc-4.3.3-avr32-rmw.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/32-gcc-4.3.3-avr32-sleep-builtin.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/33-gcc-4.3.3-avr32-ucr3fp.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/34-gcc-4.3.3-avr32-fpu.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/35-gcc-4.3.3.avr32-delay-cycles.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/40-gcc-4.3.3-avr32-fix-f32_to_f64.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/41-gcc-4.3.3-avr32-fix-f64_add.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/42-gcc-4.3.3-avr32-fix-32bit-div.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/43-gcc-4.3.3-avr32-fix-f64_cmp.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/44-gcc-4.3.3-avr32-fix-f64_div.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/45-gcc-4.3.3-avr32-fix-f64_to_f32.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/46-gcc-4.3.3-avr32-fix-32bit-div_2.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/47-gcc-4.3.3-avr32-fix-const_int_addr.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/48-gcc-4.3.3-avr32-fix-reorg_opt_bug11763.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/49-gcc-4.3.3-avr32-nan_by_zero_div.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/50-gcc-4.3.3-avr32-mxt768e.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/51-gcc-4.3.3-avr32-uc3c.patch
$ wget http://distribute.atmel.no/tools/opensource/avr32-gcc/gcc-4.3.3/52-gcc-4.3.3-avr32-uc3l0128.patch
I recommend making a patchset for the above patches before continuing. Now apply the patches:
$ cd $SRCDIR/gcc-4.3.3/
$ for patch in `cat ../../atmel-patches/gcc-4.3.3/patchset`; do patch -Np0 -i ../../atmel-patches/gcc-4.3.3/$patch; done
As we did previously with binutils; you'll need to run automake and autoreconf in gcc-4.3.3 source directory and *all* of its subdirectories.

Phew! If you got this far, give yourself another cold glass of Mountain Dew and let's keep going 8-D

Build Environment


To make things a little smoother let's setup some environment variables:
$ export BINUTILS_SRC=$SRCDIR/binutils-2.20.1
$ export KERNEL_SRC=$SRCDIR/linux-2.6.38
$ export GCC_SRC=$SRCDIR/gcc-4.3.3
$ export GLIBC_SRC=$SRCDIR/glibc-2.9
$ export BUILDDIR=~/workbench/AVR/AVR32/gcc-g++-4.3.3/xtools/build
$ export TARGETMACH=avr32-none-linux-gnueabi
$ export BUILDMACH=i686-pc-linux-gnu
$ export INSTALLDIR=~/workbench/AVR/AVR32/gcc-g++-4.3.3/avr32
$ export SYSROOTDIR=$INSTALLDIR/sysroot
Next up is to begin building.

Build binutils


$ mkdir -pv $BUILDDIR
$ mkdir -pv $BUILDDIR/binutils
$ cd $BUILDDIR/binutils
$ $BINUTILS_SRC/configure --disable-werror --build=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --with-sysroot=$SYSROOTDIR
$ make
 
# When the build fails run:
$ make -C bfd headers && make
 
$ make install

Kernel Headers


$ cd $KERNEL_SRC
$ make mrproper
$ make ARCH=avr32 favr-32_defconfig
$ mkdir -pv $INSTALLDIR/sysroot/usr
$ make ARCH=avr32 headers_check
$ make ARCH=avr32 INSTALL_HDR_PATH=$INSTALLDIR/sysroot/usr headers_install
$ cd $SRCDIR
Feel free to substitute any of the config files found in ../src/linux-2.6.38/arch/avr32/configs for make ARCH=

Bootstrap gcc


Before we can start building bootstrap gcc we need to make a change to ../src/gcc-4.3.3/libgcc/config.host:
Change this line
...
...
avr32-*-*)
    ;;
...
...
to
...
...
avr32-*-*)
    extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
    ;;
...
...
Save the file and begin the build:
$ mkdir $BUILDDIR/bootstrap-gcc
$ cd $BUILDDIR/bootstrap-gcc
$ $GCC_SRC/configure --build=$BUILDMACH --host=$BUILDMACH --target=$TARGETMACH --prefix=$INSTALLDIR --without-headers --enable-boostrap --enable-languages="c" --disable-threads --enable-__cxa_atexit --disable-libmudflap --with-gnu-ld --with-gnu-as --disable-libssp --disable-libgomp --disable-nls --disable-shared
$ make all-gcc install-gcc
Now we need to make another change. But this time to ../build/bootstrap-gcc/gcc/libgcc.mvars:
Change this
...
...
GCC_EXTRA_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o
...
...
to
...
...
GCC_EXTRA_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o
...
...
Save the file and continue with the build:
$ make all-target-libgcc install-target-libgcc
$ ln -s $INSTALLDIR/lib/gcc/avr32-none-linux-gnueabi/4.3.3/libgcc.a $INSTALLDIR/lib/gcc/avr32-none-linux-gnueabi/4.3.3/libgcc_sh.a

glibc Headers - If binutils is not compatible with glibc this is where it will fail























Atmel binutils-2.20.1 patchset


Copy & paste the cotents below into a plain text file and save the file as patchset in atmel-patches/binutils-2.20.1 that you made previously.
20-binutils.2.20.1-avr32-autoconf.patch
30-binutils-2.20.1-avr32-bfd.patch
31-binutils-2.20.1-avr32-binutils.patch
32-binutils-2.20.1-avr32-gas.patch
33-binutils-2.20.1-avr32-include.patch
34-binutils-2.20.1-avr32-ld.patch
35-binutils-2.20.1-avr32-opcodes.patch
40-binutils-2.20.1-avr32-fixes.patch
41-binutils-2.20.1-avr32-fpu.patch
42-binutils-2.20.1-avr32-bug-7435.patch
50-binutils-2.20.1-avr32-mxt768e.patch
51-binutils-2.20.1-avr32-uc3c.patch
52-binutils-2.20.1-avr32-uc3l0128.patch
53-binutils-2.20.1-avr32-uc3a4.patch
54-binutils-2.20.1-avr32-uc3d.patch
55-binutils-2.20.1-avr32-uc3l3l4.patch
return

Atmel gcc-4.3.3 patchset


Copy & paste the cotents below into a plain text file and save the file as patchset in atmel-patches/gcc-4.3.3 that you made previously.
30-gcc-4.3.3-avr32.patch
31-gcc-4.3.3-avr32-rmw.patch
32-gcc-4.3.3-avr32-sleep-builtin.patch
33-gcc-4.3.3-avr32-ucr3fp.patch
34-gcc-4.3.3-avr32-fpu.patch
35-gcc-4.3.3.avr32-delay-cycles.patch
40-gcc-4.3.3-avr32-fix-f32_to_f64.patch
41-gcc-4.3.3-avr32-fix-f64_add.patch
42-gcc-4.3.3-avr32-fix-32bit-div.patch
43-gcc-4.3.3-avr32-fix-f64_cmp.patch
44-gcc-4.3.3-avr32-fix-f64_div.patch
45-gcc-4.3.3-avr32-fix-f64_to_f32.patch
46-gcc-4.3.3-avr32-fix-32bit-div_2.patch
47-gcc-4.3.3-avr32-fix-const_int_addr.patch
48-gcc-4.3.3-avr32-fix-reorg_opt_bug11763.patch
49-gcc-4.3.3-avr32-nan_by_zero_div.patch
50-gcc-4.3.3-avr32-mxt768e.patch
51-gcc-4.3.3-avr32-uc3c.patch
52-gcc-4.3.3-avr32-uc3l0128.patch
return